/*
 * @Author: wangchao
 * @Date: 2025-06-06 13:09:05
 * @LastEditors: wangchao
 * @LastEditTime: 2025-07-10 14:50:56
 * @FilePath: \ATE-CON\applications\main.c
 * @Description:
 * Copyright (c) 2025 by Bingshan Guardian, All Rights Reserved.
 */

#include "board.h"
#include <rtdevice.h>
#include <rtthread.h>
#include <stdint.h>

#define DBG_TAG "MAIN"
#define DBG_LVL DBG_LOG

// ======================== 配置区 ========================
// #define USE_UART1_AS_INPUT // 注释此行使用 UART2 作为输入

#define DO_EN GET_PIN(B, 8)

#ifdef USE_UART1_AS_INPUT
#define INPUT_UART_NAME "uart1"
#else
#define INPUT_UART_NAME "uart2"
#endif
#define OUTPUT_UART_NAME "uart4"

// #define UART_BUF_SIZE 128
// =======================================================

static rt_device_t input_uart = RT_NULL;
static rt_device_t output_uart = RT_NULL;

static char input_buf[128];
static char output_buf[256];
static char restored_buf[256];

#if 0
void bit_expand(uint8_t input, uint8_t* out_high, uint8_t* out_low)
{
    uint16_t result = 0;

    for (int i = 7; i >= 0; i--)
    {
        result <<= 2;
        if ((input >> i) & 0x01)
        {
            result |= 0b11;  // bit=1 -> 11
        }
        else
        {
            result |= 0b01;  // bit=0 -> 01
        }
    }

    *out_high = (result >> 8) & 0xFF;
    *out_low = result & 0xFF;
}

uint8_t bit_restore(uint8_t high, uint8_t low)
{
    uint16_t input = ((uint16_t)high << 8) | low;
    uint8_t result = 0;

    for (int i = 7; i >= 0; i--)
    {
        result <<= 1;
        uint8_t two_bits = (input >> (i * 2)) & 0b11;

        if (two_bits == 0b11)
            result |= 1;
        else if (two_bits == 0b01)
            result |= 0;
        else
        {
            // 非法编码（例如 00 或 10）
            // 可以选择返回错误值，或用 assert/assert_param 宏等处理
            // 这里我们用一个特例返回 0xFF 表示出错
            return 0xFF;
        }
    }

    return result;
}
#endif

#if 0
// === 输入串口（UART1 或 UART2）回调函数 ===
static rt_err_t input_uart_rx_callback(rt_device_t dev, rt_size_t size)
{
    rt_size_t len;

    len = rt_device_read(dev, 0, input_buf, sizeof(input_buf));
    if (len > 0)
    {
        rt_kprintf("Recv from %s (%d bytes): ", INPUT_UART_NAME, len);
        for (rt_size_t i = 0; i < len; i++)
        {
            rt_kprintf("0x%02X ", (unsigned char)input_buf[i]);
        }
        rt_kprintf("\n");

        rt_pin_write(DO_EN, PIN_LOW);
        for (int i = 0; i < 100; i++)
        {
            asm volatile("nop");
        }

        // 数据展开
        rt_size_t out_idx = 0;
        for (rt_size_t i = 0; i < len; i++)
        {
            uint8_t high, low;
            bit_expand(input_buf[i], &high, &low);
            output_buf[out_idx++] = high;
            output_buf[out_idx++] = low;
        }

        // 转发展开后的数据到 UART4
        rt_device_write(output_uart, 0, output_buf, out_idx);
    }

    for (int i = 0; i < 100; i++)
    {
        asm volatile("nop");
    }
    rt_pin_write(DO_EN, PIN_HIGH);

    return RT_EOK;
}
#endif

static rt_err_t input_uart_rx_callback(rt_device_t dev, rt_size_t size)
{
    rt_size_t len;

    len = rt_device_read(dev, 0, input_buf, sizeof(input_buf));
    if (len > 0)
    {
        rt_kprintf("Recv from %s (%d bytes): ", INPUT_UART_NAME, len);
        for (rt_size_t i = 0; i < len; i++)
        {
            rt_kprintf("0x%02X ", (unsigned char)input_buf[i]);
        }
        rt_kprintf("\n");

        rt_pin_write(DO_EN, PIN_LOW);

        for (int i = 0; i < 20; i++)
        {
            asm volatile("nop");
        }

        // 转发到 UART4
        rt_device_write(output_uart, 0, input_buf, len);
    }

    for (int i = 0; i < 20; i++)
    {
        asm volatile("nop");
    }
    rt_pin_write(DO_EN, PIN_HIGH);

    return RT_EOK;
}

// === UART4 接收回调函数 ===
static rt_err_t output_uart_rx_callback(rt_device_t dev, rt_size_t size)
{
    rt_size_t len;

    len = rt_device_read(dev, 0, output_buf, sizeof(output_buf));
    if (len > 0)
    {
        rt_kprintf("Recv from %s (%d bytes): ", OUTPUT_UART_NAME, len);
        for (rt_size_t i = 0; i < len; i++)
        {
            rt_kprintf("0x%02X ", (unsigned char)output_buf[i]);
        }
        rt_kprintf("\n");

        rt_pin_write(DO_EN, PIN_HIGH);
        for (int i = 0; i < 20; i++)
        {
            asm volatile("nop");
        }

        // 透传回输入串口
        rt_device_write(input_uart, 0, output_buf, len);
    }

    return RT_EOK;
}

#if 0
static rt_err_t output_uart_rx_callback(rt_device_t dev, rt_size_t size)
{
    rt_size_t len = rt_device_read(dev, 0, output_buf, sizeof(output_buf));
    if (len > 0)
    {
        rt_kprintf("Recv from %s (%d bytes): ", OUTPUT_UART_NAME, len);
        for (rt_size_t i = 0; i < len; i++)
        {
            rt_kprintf("0x%02X ", (unsigned char)output_buf[i]);
        }
        rt_kprintf("\n");

        rt_pin_write(DO_EN, PIN_HIGH);
        for (int i = 0; i < 100; i++)
            asm volatile("nop");

        // 解码还原
        rt_size_t restored_len = 0;

        if ((len % 2) != 0)
        {
            rt_kprintf("Invalid input length for bit_restore (must be even)\n");
            return RT_EOK;
        }

        for (rt_size_t i = 0; i < len; i += 2)
        {
            uint8_t restored = bit_restore(output_buf[i], output_buf[i + 1]);
            if (restored == 0xFF)
            {
                rt_kprintf("Invalid encoded data at index %d\n", i);
                continue;
            }
            restored_buf[restored_len++] = restored;
        }

        // 透传还原后的数据到 UART2（input_uart）
        rt_device_write(input_uart, 0, restored_buf, restored_len);
    }

    return RT_EOK;
}
#endif

// === 初始化函数 ===
int uart_bi_transparent_dma_init(void)
{
    input_uart = rt_device_find(INPUT_UART_NAME);
    output_uart = rt_device_find(OUTPUT_UART_NAME);

    if (!input_uart || !output_uart)
    {
        rt_kprintf("Can't find %s or %s\n", INPUT_UART_NAME, OUTPUT_UART_NAME);
        return -1;
    }

    // === 网口配置波特率为 115200 8 N 1===
    struct serial_configure eth_config = RT_SERIAL_CONFIG_DEFAULT;
    eth_config.baud_rate = BAUD_RATE_9600;
    eth_config.data_bits = DATA_BITS_8;
    eth_config.stop_bits = STOP_BITS_1;
    eth_config.parity = 0;
    rt_device_control(input_uart, RT_DEVICE_CTRL_CONFIG, &eth_config);

    // === HBS配置波特率为 9600 8 N 1 偶校验===
    struct serial_configure hbs_config = RT_SERIAL_CONFIG_DEFAULT;
    hbs_config.baud_rate = BAUD_RATE_9600;
    hbs_config.data_bits = DATA_BITS_8;
    hbs_config.stop_bits = STOP_BITS_1;
    hbs_config.parity = 0;

    rt_device_control(output_uart, RT_DEVICE_CTRL_CONFIG, &hbs_config);

    // === 打开设备并设置回调 ===
    rt_device_open(input_uart, RT_DEVICE_FLAG_DMA_RX);
    rt_device_set_rx_indicate(input_uart, input_uart_rx_callback);

    rt_device_open(output_uart, RT_DEVICE_FLAG_DMA_RX);
    rt_device_set_rx_indicate(output_uart, output_uart_rx_callback);

    rt_kprintf("Bi-directional DMA transparent forwarding initialized: %s <--> "
               "%s @9600 baud\n",
               INPUT_UART_NAME, OUTPUT_UART_NAME);

    return 0;
}

int main(void)
{
    rt_thread_mdelay(100);

    uart_bi_transparent_dma_init();

    rt_pin_mode(DO_EN, PIN_MODE_OUTPUT);
    rt_pin_write(DO_EN, PIN_HIGH);

    while (1)
    {
        rt_thread_mdelay(5000);
    }

    return RT_EOK;
}
